#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "W25Q64Ins.h"
/*硬件驱动层*/
/*地址从0x000000到0x7FFFFF*/

uint8_t W25Q64_MID = 0;
uint16_t W25Q64_DID = 0;


//等待W25Q64不忙的函数 加入超时退出
void W25Q64_WaitBusy(void)
{
    uint32_t TimeOut = 10000;
    MySPI_Start();
    MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);
    while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)
    {
        TimeOut--;
        if (TimeOut == 0)
        {
            break;
        }
    }
    MySPI_Stop();
}

void W25Q64_WriteEnable(void)
{
    W25Q64_WaitBusy();
    MySPI_Start();
    MySPI_SwapByte(W25Q64_WRITE_ENABLE);
    MySPI_Stop();
}


//写入数据 输入地址 数据（列表的形式） 数据长度（字节） 写入需要写使能
//写入数据不能跨页 一页00-FF 多出来的会回到页首接着写
void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t DataLen)
{
    W25Q64_WaitBusy();
    W25Q64_WriteEnable();
    MySPI_Start();
    MySPI_SwapByte(W25Q64_PAGE_PROGRAM);
    MySPI_SwapByte(Address >> 16);
    MySPI_SwapByte(Address >> 8);
    MySPI_SwapByte(Address);
    while (DataLen--)
    {
        MySPI_SwapByte(*DataArray++);
    }
    MySPI_Stop();
    W25Q64_WaitBusy();
}

//Sector 擦除 写入需要写使能
void W25Q64_SectorErase(uint32_t Address)
{
    W25Q64_WaitBusy();
    W25Q64_WriteEnable();
    MySPI_Start();
    MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);
    MySPI_SwapByte(Address >> 16);
    MySPI_SwapByte(Address >> 8);
    MySPI_SwapByte(Address);
    MySPI_Stop();
    W25Q64_WaitBusy();
}

//读取一组数据 输入地址 存放数据的首地址 数据长度（字节）
//读取数据可以跨页
void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint16_t DataLen)
{
    W25Q64_WaitBusy();
    MySPI_Start();
    MySPI_SwapByte(W25Q64_READ_DATA);
    MySPI_SwapByte(Address >> 16);
    MySPI_SwapByte(Address >> 8);
    MySPI_SwapByte(Address);
    while (DataLen--)
    {
        *DataArray++ = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
    }
    MySPI_Stop();
}


//获取厂商ID和设备ID 数据存放在全局变量MID和DID中
//这里的MID为EF，DID为4017
void W25Q64_GetID(void)
{
    W25Q64_WaitBusy();
    MySPI_Start();
    MySPI_SwapByte(W25Q64_JEDEC_ID);
    W25Q64_MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
    W25Q64_DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);
    W25Q64_DID = (W25Q64_DID << 8) | MySPI_SwapByte(W25Q64_DUMMY_BYTE);
    MySPI_Stop();
}

void W25Q64_Init(void)
{
    MySPI_Init();
}

